# --! coding=utf-8 !--
# coding=utf-8
# Copyright (c) [2025] [2578713815@qq.com]
# [AHPU_EQM] is licensed under Mulan PSL v2.
"""
服务业务逻辑\n
author: <2578713815@qq.com>\n
"""
import smtplib
from email.mime.text import MIMEText  # 往邮件中写内容的对象
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr  # 发件人信息
from Utils import dbUtils, timeUtils
from CONFIG import settings
import datetime


class MsgServo:
	def __init__(self, sys_file_path: str = settings.SYS_DATA_PATH) -> None:
		"""
		初始化邮箱
		:param sys_file_path: 系统设置文件路径
		"""
		sys_data = dbUtils.get_json_info(sys_file_path)
		self.from_name = settings.SENDER
		self.msg_from = sys_data["manager_account"]
		password = sys_data["smpt_code"]
		self.mail_host = sys_data["mail_host"]
		self.mail_port = sys_data["port"]
		self.subject = settings.SUBJECT
		self.s = smtplib.SMTP_SSL("smtp.qq.com", 465)
		self.s.login(self.msg_from, password)

	def send(self, msg_content: str, msg_to: list) -> int:
		"""
		发送邮件
		:param msg_content: 服务商邮箱
		:param msg_to: 发送对象邮箱
		:return:
		"""
		print(settings.GREEN + f">>> 发送信息:{msg_content}" + settings.RESET)
		# msg = MIMEText(msg_content, 'plain', 'utf-8')
		msg = MIMEMultipart()
		msg['From'] = formataddr((self.from_name, self.msg_from))
		msg['to'] = msg_to
		msg['Subject'] = self.subject
		msg.attach(MIMEText(msg_content, 'plain', 'utf-8'))
		try:
			self.s.sendmail(self.msg_from, msg_to, msg.as_string())
			return 0x000
		except Exception as e:
			print(settings.RED + ">>> Send mail failed:" + settings.RESET, e)
			return 0x006

	def quit(self):
		self.s.quit()


class User:
	"""
	用户对象, 用于存储用户信息
	"""
	def __init__(self, user_data:list) -> None:
		self.user_account = user_data[0]
		self.build = user_data[1]
		self.room = user_data[2]
		self.mode = user_data[3]
		self.limit = user_data[4]
		self.warn = user_data[5]
		self.statu = user_data[6]


def servo_mode0(user_data: list, user_num: int):
	"""
	模式0的用户服务逻辑
	:param user_data: 单条用户数据
	:param user_num: 用户总量，决定事件范围判断（每个用户需要占用3秒）
	:return: 状态码 0x000 | 0x001
	"""
	user = User(user_data)
	now_time = datetime.datetime.now()
	if timeUtils.check_current_time(7, 0, 0, user_num*settings.SEND_TIME_INTERVAL+1):
		# 模式0, 当天7:00发送电量信息
		electric = dbUtils.get_electric_with_build_room(user.build, user.room)
		if electric == -999.:
			return 0x002
		return servo_msg_send_mode_0_1(user, electric, now_time)
	else:
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 非发送时段 |")
		return 0x005


def servo_mode1(user_data: list, user_num: int):
	"""
	模式1的用户服务逻辑
	:param user_data: 单条用户数据
	:param user_num: 用户总数量
	:return: 状态码 0x000 | 0x001
	"""
	user = User(user_data)
	now_time = datetime.datetime.now()
	if (timeUtils.check_current_time(7, 0, 0, _tolerance_second_=user_num*settings.SEND_TIME_INTERVAL+1)
			or timeUtils.check_current_time(19, 0, 0, _tolerance_second_=user_num*settings.SEND_TIME_INTERVAL+1)):
		# 模式1, 当天7:00与19:00发送电量信息
		electric = dbUtils.get_electric_with_build_room(user.build, user.room)
		if electric == -999.:
			dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 查询失败 |")
			return 0x002
		return servo_msg_send_mode_0_1(user, electric, now_time)
	else:
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 非发送时段 |")
		return 0x005


def servo_msg_send_mode_0_1(user: User, electric: float, now_time: datetime.datetime.now) -> int:
	"""
	模式0/1的信息发送函数
	:param user: User对象
	:param electric: 电量
	:param now_time: 当前时间对象
	:return:
	"""
	if electric < float(user.limit):
		info_tail = settings.INFO_LIMIT
	elif float(user.limit) < electric < float(user.warn):
		info_tail = settings.INFO_WARN
	else:
		info_tail = settings.INFO_ENOUGH
	msg = f"{settings.INFO_HEADER}{user.build}-{user.room}\n{settings.INFO_BODY} : {electric} | {info_tail}"
	msg_save = rf"{settings.INFO_HEADER}{user.build}-{user.room}\n{settings.INFO_BODY} : {electric} | {info_tail}"
	try:
		msg_servo = MsgServo(settings.SYS_DATA_PATH)
		res = msg_servo.send(msg_content=msg, msg_to=user.user_account)
		msg_servo.quit()
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 发送成功 | <{msg_save}>")
		return res
	except Exception as e:
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 发送失败 | <{e}>")
		return 0x006


def servo_mode2(user_data: list, msg_servo: MsgServo):
	pass


def servo_mode3(user_data: list, msg_servo: MsgServo):
	pass


def servo_mode4(user_data: list, user_num: int):
	"""
	模式4的用户服务逻辑
	:param user_data: 单条用户数据
	:param user_num: 用户总数
	:return: 十六进制状态码
	"""
	user = User(user_data)
	now_time = datetime.datetime.now()
	e_data = dbUtils.get_electric_with_build_room(user.build, user.room)
	if e_data == -999.:
		return 0x002
	try:
		limit = float(user.limit)
	except ValueError:
		return 0x003
	if e_data <= limit and user.statu == "0":
		electric = dbUtils.get_electric_with_build_room(user.build, user.room)
		msg = f"{settings.INFO_HEADER}{user.build}-{user.room}\n{settings.INFO_BODY} : {electric} | {settings.INFO_LIMIT}"
		msg_save = rf"{settings.INFO_HEADER}{user.build}-{user.room}\n{settings.INFO_BODY} : {electric} | {settings.INFO_LIMIT}"
		try:
			msg_servo = MsgServo(settings.SYS_DATA_PATH)
			res = msg_servo.send(msg_content=msg, msg_to=user.user_account)
			msg_servo.quit()
			dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 发送成功 | <{msg_save}>")
			if res == 0x000:
				dbUtils.set_user_info_statu(user.user_account, user.build, user.room, user.mode)
			return res
		except Exception as e:
			dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 发送失败 | <{e}>")
			return 0x006
	elif e_data > limit:
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 电量充足 无需发送 |")
		return 0x004
	elif user.statu == "1":
		dbUtils.append_log(f"{now_time.strftime('%Y-%m-%d %H:%M:%S')} | {user.user_account} | 当日信息已推送 无需发送 |")
		return 0x001
	else:
		return 0x004


servo_funcs = [
	servo_mode0,
	servo_mode1,
	servo_mode2,
	servo_mode3,
	servo_mode4
]
'不同消息模式下的用户服务函数列表'
